# coding:utf-8
from __future__ import print_function
import sys, datetime

rootpath = "D:/OneDriveEdu/file/project/grpc_w2m_framework_m/worker/yuqing"
sys.path.append(rootpath)
import worker.yuqing.crawler.spider.BingStarter as bingEntrance
import worker.yuqing.crawler.spider.WeiboStarter as weiboEntrance
import worker.yuqing.crawler.spider.utils as utils
from worker.yuqing.crawler.ArticleExtractor import Extractor
from worker.yuqing.crawler.Similarity.Manage import Manage
from worker.yuqing.crawler.KeyWords import getTimeAddress
import pymysql
import pymongo
from pymongo.errors import DuplicateKeyError
import logging
import paddlehub as hub
import pandas as pd
import json


class MongoDBPipeline_MenHu():
    def __init__(self):
        client = pymongo.MongoClient("localhost", 27017)
        db = client['PublicNewsComments']
        self.Users = db["Users"]
        self.Tweets = db["yuqing_originnews"]

    def process_item(self, item):
        self.insert_item(self.Tweets, item)
        return item

    @staticmethod
    def insert_item(collection, item):
        try:
            collection.insert(dict(item))
        except DuplicateKeyError:
            pass


class MysqlPipeline_MenHu():  # 信息处理

    def __init__(self, mylogger):  # 连接数据库data
        self.db = pymysql.connect(db='platform', host='localhost', port=3306, user='root', passwd='123',
                                  charset='utf8mb4')
        self.cursor = self.db.cursor()
        self.logger = mylogger
        self.senta = hub.Module(name="senta_bilstm")

    def process_item(self, item):  # 同步更新云端数据库
        item_id = ''
        keys_list = ['news_title', 'news_link', 'news_author', 'news_timeStamp',
                     'news_comments_link', 'news_comments',
                     'news_site', 'image_url', 'origin_weibo', 'news_content',
                     'exceptiondesc', 'news_calorificvalue', 'news_abstract', 'news_keywords']
        for k in item.keys():
            item[k] = str(item[k]).replace(r"'", r"\'")
            item[k] = bytes(item[k], 'utf-8').decode('utf-8', 'ignore')
        for key in keys_list:
            if key not in item.keys():
                item[key] = ''
        # print(item['news_comments'])
        if (item['news_link'] == ''):
            self.logger.warn("空数据，跳过")
        else:
            news_link = item['news_link']
            print(news_link + '\n' + item['news_content'])
            sql = r"select * from yuqing_originnews where news_link='" + news_link + "'"
            # print(sql)
            self.cursor.execute(sql)
            results = self.cursor.fetchall()
            # print("查到记录：\n", results)

            if (results):  # 如果存在这条新闻，更新旧新闻的评论和热度值
                # work_sql = r"select * from yuqing_originnews where 'news_link'=" + news_link
                work_sql = "update yuqing_originnews set " \
                           "news_comments= '%s', news_calorificvalue='%s', news_abstract='%s', news_keywords='%s'" \
                           " where news_link= '%s'" % \
                           (item['news_comments'], item['news_calorificvalue'],
                            item['news_abstract'], str(item['news_keywords']),
                            item['news_link'])
                print("执行sql：", work_sql)
                # print("更新评论信息：", item['news_comments'])
                self.cursor.execute(work_sql)
                item_id = results[0][0]
                # print(item_id)
                self.db.commit()
                self.logger.info(work_sql)
                # print("更新 ：" + news_link)
            else:  # 新增数据

                work_sql = "insert into yuqing_originnews(" \
                           "news_title, news_link, news_author, news_timeStamp, news_comments_link, " \
                           "news_comments, news_site, image_url, origin_weibo, news_content, exceptiondesc, " \
                           "news_calorificvalue, news_abstract, news_keywords, elements_address, elements_time) " \
                           "values('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')" % (
                               item['news_title'], item['news_link'], item['news_author'], item['news_timeStamp'],
                               item['news_comments_link'], item['news_comments'], item['news_site'], item['image_url'],
                               item['origin_weibo'], item['news_content'], item['exceptiondesc'], item['news_calorificvalue'],
                               item['news_abstract'], item['news_keywords'], item['elements_address'], item['elements_time'])

                print("执行sql：", work_sql)
                self.logger.info(work_sql)
                self.cursor.execute(work_sql)
                item_id = self.cursor.lastrowid
                self.db.commit()
        print("======================")
        return item_id

    def article_extractor_process(self, item):
        text = item['news_content']
        # print(text)
        # text = "江苏泰兴市应急管理局通报，4月3日晚9时许，江苏中丹技术化工有限公司污水车间废水储罐发生一起火灾事故。截至当晚9时30分，明火已经扑灭，事故未造成人员伤亡，事故原因正在调查之中。这是继江苏响水天嘉宜化工有限公司“3·21”爆炸发生后的又一起事故。21世纪经济报道记者了解到，近期江苏、浙江、河北、福建等沿海省份密集提出新一轮的化工行业大整治措施。江苏省长吴政隆主持召开专题会议，研究全省化工行业整治提升工作；浙江生态环境厅近期发出了对化工企业安全隐患排查整治专项行动的紧急通知，决定部署开展为期2个月的专项行动，排查整治范围包括全省所有化工园区和化工企业。河北提出对化工商业实施安全生产实施整治攻坚行动，时间一直持续到2020年12月；福建提出对整改仍然达不到要求的化工企业，要坚决停用。据了解，化工行业整治行动几乎年年都有，但相关事故仍屡见不鲜。南通大学特聘教授徐长乐指出，化工产业本身有升级换代的问题，一些设备的更新、技术工艺的升级都是很重要的，以求把产品的危害降到最低。同时大江大河以及一些水源地附近的化工企业有必要进行搬迁。“另外对于一些危害性比较强、安全不到位的企业，该关停的就要关停，通过整治来淘汰一部分的落后产能，防患于未然。”徐长乐说。全面清查，坚决整治此前3月21日江苏响水县发生化工爆炸事故，截至3月25日下午16时，造成78人死亡。痛定思痛，多个沿海省份密集采取了安全整治行动。根据新华日报的消息，近期江苏省长吴政隆主持召开专题会议，提出对化工行业布局要更优化，对沿长江干支流两侧1公里范围内、环境敏感区域、城镇人口密集区、化工园区外、规模以下等化工企业，该停的坚决停，该关的坚决关，该搬的坚决搬，以壮士断腕的决心着力破解“重化围江”“低散乱污危”等突出问题。河北提出，将在全省范围内开展为期两年的化工行业安全生产整治攻坚行动。对列入整治范围的所有化工企业和园区，开展一次全覆盖、地毯式排查，不留死角盲区。全面摸清安全生产现状、风险源点等情况，建立辖区内园区和企业的台账清单，做到“一企一档”“一园一档”。浙江提出，用2个月时间，各城市生态环境局主要负责人带队赴重点化工企业、园区检查，坚持“发现一起，记录一起，整改一起”，杜绝任何表面整改和形式整改，确保风险隐患可控和有效治理。福建提出，各级应急（安监）部门对于化工行业要开展暗查暗访、联合执法、集中执法，保持高压态势。要加大危险化学品企业违法违规行为处罚力度，严格落实关闭取缔、上限处罚、停产整顿、追究法律责任措施。大宗商品服务商金联创行业总监王贞贤认为，化工行业强化管理很重要。本来化工企业需要入园集中管理， 但是由于地方税收、历史遗留问题等种种原因，目前政策的实际执行情况各地都不同。河海大学教授刘奇洪指出，比如日本和德国的安全生产不只是限于制度规范，甚至已经深入到文化层面，但中国很多化工企业为了降低成本，对安全生产不重视。“如果很多企业对安全生产只是采取应付的态度，那么未来仍会有新的问题发生。”刘奇洪说。事关产业升级21世纪经济报道记者了解到，中国沿海省份是化工生产的重要基地，几乎年年在整治，但仍有相当规模。以山东为例，去年化工专项行动共关闭转产化工企业620家，停产整顿2614家，下一步还将在该基础上关闭20%以上，将全省化工生产企业控制在5000家以内。而据河北最近刚刚披露的数据，全省现有危险化学品生产经营单位10825家，其中生产企业754家、经营企业10071家，2016年以来，河北共发生生产安全事故19起。本次各地实施化工行业整治行动，大多直接提出对不达标的企业实施停产措施，同时强调产业的提升改造。河北省提出，关停取缔一批，对不具备安全生产条件的企业依法依规关闭取缔；搬迁入园一批，对位于城市人口密集区、不满足安全防护距离要求的企业加快搬迁入园，原则上危化品企业全部进入化工园区；另外要提升改造一批，做强做优一批。对列入搬迁入园、改造提升、做强做优名单的企业，强化动态跟踪，一旦发现重大现实隐患且达不到安全生产条件的，先停产后整治，验收合格才能复产。江苏也提出，化工园区定位要更准确，将上下游关联度高、安全可控的企业集中到园区，严格实行封闭管理，切实提高绿色、低碳、循环、智能、安全运行水平。准入门槛和标准要更高，从安全、环保、技术、能耗、亩均效益等方面提高标准，同时，制定更科学的产业负面清单。  南通大学特聘教授徐长乐指出，化工企业是否按照合理的流程、规则在操作，这需要实地做好检查。有些企业为了降低成本开支，安全设施不到位，或者有安全设施但没有使用，原因是为了节省高额成本。 徐长乐还指出，对于一些危害性比较强、安全不到位的企业，该关停的就要关停，通过整治来淘汰一部分落后产能，防患于未然。据了解，很多地方的化工产业园区选址在城区，经过多年发展后，很多化工企业面临搬迁的问题。刘奇洪指出，很多国家新区同时也是化工园区，这个定位是有问题的，在主城区发展化工行业危险性高，过去包括北京等很多城市的化工产业已经在搬迁，但仍有一些城市有大量的化工园区。“实际上江苏一些苏北城市的化工就是从苏南迁来的，苏北一些城市为了做大经济总量，吸引了这些产业，但这对城市未来的一些新产业发展造成了难题，比如如果大力发展化工产业，城市的旅游业等会受到影响。”刘奇洪说。"
        extractor = Extractor(stop_words_file=rootpath + '/crawler/TextRank/trainer/stopword_zh.data')
        keyword, keyphrase = extractor.keyword_train(text=text)
        # abstract = extractor.sentence_train(text, sentences_percent='20%')
        abstract = '。'.join(extractor.sentence_train(text, sentences_percent='50%')) + '。'
        print(abstract, "\n", keyword)
        item['news_abstract'] = abstract
        item['news_keywords'] = keyword

        model = getTimeAddress.time_address_extract_model()
        segmentor, postagger, recognizer = model.get_model()
        address_list, time_list = getTimeAddress.get_elements(segmentor, postagger, recognizer, text)
        # model.free_model()
        item['elements_address'] = address_list
        item['elements_time'] = time_list

        return item

    def comment_sentiment_process(self, item):
        # print(item['news_comments'])
        # comments = eval(item['news_comments'].replace("\\'","'"))
        comments = item['news_comments']
        if len(comments) == 0:
            pass
        else:
            for comments_item in comments:
                # print(comments_item)
                # comments_item_id = comments_item['comment_id']
                comments_item_content = comments_item['comment_content']
                positive_probs = utils.getSentimentResults(self.senta, comments_item_content)
                # print(item_id, comments_item_id, comments_item_content, positive_probs)
                # 插入数据
                comments_item['positive_probs'] = positive_probs
                if positive_probs > 0.65:
                    comments_item['emotion'] = "积极"
                elif positive_probs > 0.35:
                    comments_item['emotion'] = "中性"
                else:
                    comments_item['emotion'] = "消极"
        item['news_comments'] = comments
        return item

    def get_similarity(self):
        self.get_articles()
        return 'success'

    def get_articles(self):
        # work_sql = "select id,news_title,news_content from yuqing_originnews where news_link='https://www.thepaper.cn/newsDetail_forward_9808055'"
        work_sql = "select id,news_title,news_content from yuqing_originnews"
        work_sql2 = "select id,news_title,news_content from yuqing_originnews where news_link='https://news.163.com/20/1101/19/FQCCJ9DG0001899O.html'"
        self.logger.info(work_sql)
        self.cursor.execute(work_sql)
        results1 = self.cursor.fetchall()
        self.cursor.execute(work_sql2)
        results2 = self.cursor.fetchall()
        results1 = pd.DataFrame(results1, columns=['news_id', 'news_title', 'news_content'])
        results2 = pd.DataFrame(results2, columns=['news_id', 'news_title', 'news_content'])
        articles_content = results1.to_dict().get('news_content')
        news_content = {'0': results1.to_dict().get('news_content').get(20)}
        articles_id = results1['news_id'].tolist()
        print(type(articles_content))
        print(Manage(news_content, articles_content).get_local_analyse())


def logger(log_path):
    logger = logging.getLogger("Test")  # 定义一个logger
    # log_path = "./log.txt"  # 输出的文件位置
    fh = logging.FileHandler(log_path, mode="w")  # 定义一个文件的logger handler, 模式默认为在尾部添加，"w"会先删除内容，然后再写log
    fh.setLevel(logging.DEBUG)  # 设置输出的级别，只有级别不低于该级别的才会输出
    # 创建输出格式
    fmt = "%(asctime)s %(filename)s[line:%(lineno)d]: %(levelname)s %(message)s"
    datefmt = "%a %d %b %Y %H:%M:%S"
    formatter = logging.Formatter(fmt, datefmt)  # 获得输出格式对象
    fh.setFormatter(formatter)  # 为handler设置输出的格式
    logger.addHandler(fh)  # 为logger指定handler
    return logger


def run(key_words):
    mylogger = logger("D:/OneDriveEdu/file/project/grpc_w2m_framework_m/worker/yuqing/crawler/log/log.txt")
    # key_words = ['化工爆炸', '化工泄露', '化工中毒', '化工火灾']
    # 1.用于启动必应搜索和微博搜索
    # 2.将数据字段最后进行统一，存入数据库，现在暂定为json格式

    # 1.1 启动必应（必应吊起门户网站爬虫）
    pipeline = MysqlPipeline_MenHu(mylogger)
    url_dict, news163_dicts, newsQQ_dicts, newsThepaper_dicts = bingEntrance.BingStarter(key_words=key_words)

    for item in news163_dicts:
        # 先保存原文
        # item_id = pipeline.process_item(item)
        # 再判断分类和评论情感分类 插入库
        item = pipeline.comment_sentiment_process(item)
        if item['news_content'] != None:
            item = pipeline.article_extractor_process(item)
        if item['exceptiondesc'] == 'init':
            item_id = pipeline.process_item(item)
    for item in newsQQ_dicts:
        item = pipeline.comment_sentiment_process(item)
        if item['news_content'] != None:
            item = pipeline.article_extractor_process(item)
        if item['exceptiondesc'] == 'init':
            item_id = pipeline.process_item(item)
    for item in newsThepaper_dicts:
        item = pipeline.comment_sentiment_process(item)
        if item['news_content'] != None:
            item = pipeline.article_extractor_process(item)
        if item['exceptiondesc'] == 'init':
            item_id = pipeline.process_item(item)
    # 1.2 启动微博爬虫
    for item in weiboEntrance.weibostarter(keywords=key_words):
        # print(item)
        item = pipeline.comment_sentiment_process(item)
        if item['news_content'] != None:
            item = pipeline.article_extractor_process(item)
        if item['exceptiondesc'] == 'init':
            item_id = pipeline.process_item(item)
    print("===================  本次爬取执行完毕。 " + str(datetime.datetime.now()) + "  ===================")
    return 'success'


def calu_similarity():
    """
        计算当前新文章与库中文章的相似度，并获得判断雷同的文章编号和相似度，插入当前记录中
    :return:
    """
    mylogger = logger("D:/OneDriveEdu/file/project/grpc_w2m_framework_m/worker/yuqing/crawler/log/log.txt")
    pipeline = MysqlPipeline_MenHu(mylogger)
    pipeline.get_similarity()
    return 'success'


if __name__ == '__main__':
    # run(key_words=['化工爆炸', '化工泄露', '化工中毒', '化工火灾'])
    run(key_words=['化工爆炸'])
    # 再判断相似度
    # calu_similarity()
